#include "BulletManager.h"
#include "GameUtil.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;

BulletManager::BulletManager(CCLayer* layer)
{
	d_layer = layer;
	d_enemyBullets = new CCArray;
	d_playerBullets = new CCArray;
	CCSize fieldSize = GameUtil::instance()->getSetting()->getFieldSize();  
	d_field = CCRectMake(0, 0, fieldSize.width, fieldSize.height);
}

BulletManager::~BulletManager(void)
{
	d_enemyBullets->~CCArray();
	d_playerBullets->~CCArray();
}

void BulletManager::shoot(Creature* creature, float angle)
{
	if(creature->getObjType() == OBJ_TYPE_ENEMY) {
		angle = 180 - angle;
	}

	Bullet* bullet = Bullet::create(creature->getBulletType(),
		creature->getBulletSpeed(),
		creature->getBulletDamage(),
		creature->getObjType(),
		angle);

	float x;

	switch (creature->getObjType())
	{
	case OBJ_TYPE_ENEMY:
		d_enemyBullets->addObject(bullet);
		x = creature->getRect().getMinX() - bullet->getContentSize().width/2;
		break;
	case OBJ_TYPE_PLAYER:
	case OBJ_TYPE_TOOTH:
		d_playerBullets->addObject(bullet);
		x = creature->getRect().getMaxX() + bullet->getContentSize().width/2;
		break;
	default:
		break;
	}
	bullet->setPosition(ccp(x, creature->getPositionY()));

	d_layer->addChild(bullet);
	bullet->fire();
}

void BulletManager::checkCollision()
{
	CCArray *collidedBullets = CCArray::create();
	collidedBullets->retain();

	// enemy bullets
	for (unsigned int i = 0; i < d_enemyBullets->count(); i++) {
		Bullet *bullet = (Bullet *)d_enemyBullets->objectAtIndex(i);
		checkCollisionField(collidedBullets, bullet);
		checkCollisionEnemy(collidedBullets, bullet);
	}
	
	// player bullets
	for (unsigned int i = 0; i < d_playerBullets->count(); i++) {
		Bullet *bullet = (Bullet *)d_playerBullets->objectAtIndex(i);
		checkCollisionField(collidedBullets, bullet);
		checkCreaturesHit(collidedBullets, bullet, 
			GameUtil::instance()->getEnemyManager()->getEnemys());
	}
	
	// clear bullet
	for (unsigned int k = 0; k < collidedBullets->count(); k++) {
		Bullet *bullet = (Bullet *)collidedBullets->objectAtIndex(k);
		switch (bullet->d_ownerObjType)
		{
		case OBJ_TYPE_ENEMY:
			d_enemyBullets->removeObject(bullet);
			break;
		case OBJ_TYPE_PLAYER:
		case OBJ_TYPE_TOOTH:
			d_playerBullets->removeObject(bullet);
			break;
		default:
			break;
		}
		d_layer->removeChild(bullet);
	}
}

void BulletManager::checkCollisionEnemy(CCArray *collidedBullets, Bullet *bullet)
{
	Player* player = GameUtil::instance()->getPlayer();
	Shield* shield = GameUtil::instance()->getShield();
	if(shield->isActive() && shield->getRect().intersectsRect(bullet->getRect())) {
		shield->hit(bullet->d_damage);
		collidedBullets->addObject(bullet);
	} else if(player->getHitRect().intersectsRect(bullet->getRect())) {
		player->hit(bullet->d_damage);
		collidedBullets->addObject(bullet);
	} else {
		checkCreaturesHit(collidedBullets, bullet, 
			GameUtil::instance()->getToothManager()->getTeeth());
	}
}

void BulletManager::checkCreaturesHit(CCArray *collidedBullets, Bullet *bullet, CCArray *creatures)
{
	for(int i = (int)(creatures->count())-1; i >= 0; i--)
	{
		Creature *creature = (Creature *)creatures->objectAtIndex(i);
		if(creature->isLive() && creature->getHitRect().intersectsRect(bullet->getRect())) {
			creature->hit(bullet->d_damage);
			collidedBullets->addObject(bullet);
			break;
		}
	}
}

void BulletManager::checkCollisionField(CCArray *collidedBullets, Bullet *bullet)
{
	// out of battle field
	if(!bullet->getRect().intersectsRect(d_field)) {
		collidedBullets->addObject(bullet);
	}
}